package com.gwctv.config;


import com.gwctv.interceptor.JwtTokenAdminInterceptor;
import com.gwctv.interceptor.JwtTokenUserInterceptor;
import com.gwctv.json.JacksonObjectMapper;
import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.info.Contact;
import io.swagger.v3.oas.models.info.Info;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.cbor.MappingJackson2CborHttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.*;

import java.util.List;

/**
 * 配置类，注册web层相关组件
 * @Configuration 标识此类为配置类
 * @Slf4j 输出日志
 */
@Configuration
@Slf4j
public class WebMvcConfiguration implements WebMvcConfigurer {

    //自动注入
    @Autowired
    private JwtTokenAdminInterceptor jwtTokenAdminInterceptor;
    @Autowired
    private JwtTokenUserInterceptor jwtTokenUserInterceptor;

    /**
     * 注册自定义拦截器
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry){
        log.info("开始注册自定义拦截器...");
        registry.addInterceptor(jwtTokenAdminInterceptor)
                .addPathPatterns("/admin/**")
                // 将登录操作排除
                .excludePathPatterns("/admin/employee/login");

        registry.addInterceptor(jwtTokenUserInterceptor)
                .addPathPatterns("/user/**")
                .excludePathPatterns("/user/user/login")
                .excludePathPatterns("/user/shop/status");

    }

    /**
     * 通过Knife4j生成接口文档
     * OpenAPI方法的应用参照网址 https://openapi.apifox.cn/
     * @return
     * @Bean注解在配置类中就是将OpenAPI类的bean对象交给spring容器管理，bean名称默认是
     * 方法名
     */
    @Bean
    public OpenAPI openAPI() {
        return new OpenAPI()
                .info(new Info()
                        .title("苍穹外卖项目")
                        .version("1.0")
                        .description("苍穹外卖项目学习")
                        .termsOfService("https://xxxxxx.com")
                        .contact(new Contact().name("gwc").url("https://test.com").email("test@gmail.com"))
                );
    }

    /**
     * 扩展springMVC框架的消息转换器，对后端响应给前端的数据进行统一处理，
     * 比如：这里对后端响应给前端的日期进行统一格式化
     * @param converters
     */
    @Override
    public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
        log.info("扩展的消息转换器...");
        // 创建一个消息转换器对象
        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        // 需要为消息转换器对象设置一个对象转换器，对象转换器可以将java对象序列化为json数据
        converter.setObjectMapper(new JacksonObjectMapper());
        // 将自定义的消息转换器加入到spring MVC的消息转换器集合converters中
        // converters是List集合，List集合特点存取有序、有索引、其中元素可重复
        // 注意：converters集合中，springMVC框架自带了很多消息转换器，使用add()方法，那么我们自己创建
        // 的消息转换器相当于排在converters集合中的最后面，默认使用的还是springMVC框架给我们提供的消息
        // 转换器；我们现在的需求是优先使用我们自定义的消息转换器，那么我们就需要我们自定义的消息转换器
        // 加入到converters集合中索引为0的位置，自定义转换器就排在第一位，就会优先使用
        converters.add(0,converter);
    }
}











